package org.hydrakyoufeng.stuplatform.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.qiniu.storage.DownloadUrl;
import com.qiniu.util.Auth;
import org.hydrakyoufeng.stuplatform.config.QiniuConfig;
import org.hydrakyoufeng.stuplatform.service.QiniuService;
import org.hydrakyoufeng.stuplatform.utils.ResultEntity;
import org.hydrakyoufeng.stuplatform.vo.QiniuTokenVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.Base64;
import java.util.Map;

@Service
public class QiniuServiceImpl implements QiniuService {

    private final QiniuConfig.QiniuProperties qiniuProperties;

    private final QiniuConfig.QiniuProperties qiniuSecretProperties;

    /**
     * 公开空间token的失效时间
     */
    private long deadline = 0;

    /**
     * 公开空间的token
     */
    private String token;

    /**
     * 私有空间token的失效时间
     */
    private long deadlineSecret = 0;

    /**
     * 私有空间的token
     */
    private String tokenSecret;

    @Autowired
    public QiniuServiceImpl(
            @Qualifier("qiniuProperties") QiniuConfig.QiniuProperties qiniuProperties,
            @Qualifier("qiniuSecretProperties") QiniuConfig.QiniuProperties qiniuSecretProperties
            ) {
        this.qiniuProperties = qiniuProperties;
        this.qiniuSecretProperties = qiniuSecretProperties;
    }


    @Override
    public ResultEntity getToken() throws Exception {
        Auth auth = Auth.create(qiniuProperties.getAccessKey(), qiniuProperties.getSecretKey());
        // 在失效时间之前，都是用原来的token，避免重复获取token
        if (deadline*1000 - System.currentTimeMillis()  <= 60 * 1000) {
            token = auth.uploadToken(qiniuProperties.getBucket());
            int index = token.lastIndexOf(':');
            String tokenBuffer = new String( Base64.getMimeDecoder().decode(token.substring(index+1)));
            Map<?, ?> map = new ObjectMapper().readValue(tokenBuffer, Map.class);
            try {
                deadline = Long.valueOf(String.valueOf(map.get("deadline")));
            } catch (Exception e) {
                e.printStackTrace();
                deadline = 0;
            }
        }
        QiniuTokenVO qiniuTokenVO = new QiniuTokenVO();
        qiniuTokenVO.setToken(token);
        qiniuTokenVO.setRemoteAddr(qiniuProperties.getRemoteAddr());
        return ResultEntity.success("获取成功",qiniuTokenVO);
    }

    @Override
    public ResultEntity getTokenSecret() throws Exception {
        Auth auth = Auth.create(qiniuSecretProperties.getAccessKey(), qiniuSecretProperties.getSecretKey());
        // 在失效时间之前，都是用原来的token，避免重复获取token
        if (deadlineSecret*1000 - System.currentTimeMillis()  <= 60 * 1000) {
            tokenSecret = auth.uploadToken(qiniuSecretProperties.getBucket());
            int index = tokenSecret.lastIndexOf(':');
            String tokenBuffer = new String( Base64.getMimeDecoder().decode(tokenSecret.substring(index+1)));
            Map<?, ?> map = new ObjectMapper().readValue(tokenBuffer, Map.class);
            try {
                deadlineSecret = Long.valueOf(String.valueOf(map.get("deadline")));
            } catch (Exception e) {
                e.printStackTrace();
                deadlineSecret = 0;
            }
        }
        QiniuTokenVO qiniuTokenVO = new QiniuTokenVO();
        qiniuTokenVO.setToken(tokenSecret);
        qiniuTokenVO.setRemoteAddr(qiniuSecretProperties.getRemoteAddr());
        return ResultEntity.success("获取成功",qiniuTokenVO);
    }

    @Override
    public ResultEntity<String> getSourceURL(String key) throws Exception {
        // 获取域名：将配置的域名去掉https://
        String domain = qiniuSecretProperties.getRemoteAddr().replace("https://","");
        DownloadUrl url = new DownloadUrl(domain, true, key);
        // 设置过期时间，单位：秒，1小时，可以自定义链接过期时间
        long expireInSeconds = 3600;
        long deadline = System.currentTimeMillis() / 1000 + expireInSeconds;
        Auth auth = Auth.create(qiniuSecretProperties.getAccessKey(), qiniuSecretProperties.getSecretKey());
        return ResultEntity.success("获取成功",url.buildURL(auth, deadline));
    }

}
